 /*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package PacketHandling;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryonet.Client;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.minlog.Log;
import horizon.entity.Entity;
import horizon.map.Chunk;
import horizon.network.ChunkEncoder;
import horizon.network.NetChunk;
import horizon.network.Packet;
import horizon.network.Packet.PKT_TYPE;
import horizon.util.Vector2;
import java.io.IOException;
import java.util.ArrayList;

/**
 *
 * @author J_Laptop
 */
public class PacketHandler {

    String name = "";
    long lastUpdateTime;
    Client client;
    Packet currentRequest = new Packet();
    String movementUpdate = "";
    int packetNumber = 0;
    int packetRecieved = 0;
    ArrayList<Chunk> downloadedChunk = new ArrayList<>();
    ArrayList<Entity> entityList = new ArrayList<>();
    private static PacketHandler instance;

    public static PacketHandler getInstance() {
        return instance;
    }

    public PacketHandler() {

        client = new Client();

        instance = this;

    }

    public boolean connect() {
        client.start();
        Log.set(Log.LEVEL_TRACE);
        Kryo kryo = client.getKryo();

        kryo.register(NetChunk.class);
        kryo.register(Packet.class);
        kryo.register(Packet.PKT_TYPE.class);
        kryo.register(byte[].class);

        try {
            client.connect(5000, "5.128.37.224", 54555, 54777);
        } catch (IOException ex) {
            //Logger.getLogger(PacketHandler.class.getName()).log(Level.INFO, null, ex);
            client.close();
            client.stop();
            return false;
        }

        client.addListener(new Listener() {

            public void received(Connection connection, Object object) {
                if (object instanceof Packet) {
                    Packet request = (Packet) object;

                    PacketParser parse = new PacketParser(request);


                }
                if (object instanceof NetChunk) {
                    NetChunk chunk = (NetChunk) object;

                    downloadedChunk.add(ChunkEncoder.decodeChunk(chunk));
                    packetRecieved++;

                }
            }
        });


        return true;
    }

    public Client getClient() {
        return client;
    }

    public void addMovementUpdate(Vector2 currentPos, Vector2 move) {

        movementUpdate = "mov:" + currentPos + ":" + move + ";";
      
    }

    public void addWorldDataRequest() {

        currentRequest._data += "req:worldData;";

    }

    public void sendRegisterPacket(String name) {

        Packet n = new Packet();
        n.auth = name;
        n.header = PKT_TYPE.CL_REG;

        sendPacket(n);

    }
    public void sendChatMessage(String m){
        
        currentRequest._data += "cha:" + m + ";";
        
    }
    public void sendCurrentRequest() {

        currentRequest.header = PKT_TYPE.CL_DATA;
        currentRequest.auth = name;
        currentRequest._data += movementUpdate;
        movementUpdate = "";

        if (currentRequest._data.length() > 0) {

            sendPacket(currentRequest);
            
            currentRequest = new Packet();

        }

    }

    private void sendPacket(Packet p) {

        p.sendTime = System.currentTimeMillis();
        client.sendTCP(p);

    }

    public int getPacketNumber() {
        return packetNumber;
    }

    public int getPacketRecieved() {
        return packetRecieved;
    }

    public ArrayList<Chunk> getAvailableMapChunks() {
        ArrayList<Chunk> ret = new ArrayList<>(downloadedChunk);

        downloadedChunk.clear();

        return ret;
    }
    public ArrayList<Entity> getAvailableEntities() {
        ArrayList<Entity> ret = new ArrayList<>(entityList);

        entityList.clear();

        return ret;
    }

    public String getName() {
        return name;
    }
}
